<?php
namespace App\Wen\Utils;

use App\Http\Controllers\Api\Repositories\PostsRepositores;
use App\Http\Controllers\Api\Repositories\WxCircleRepositores;
use App\Http\Controllers\Api\Repositories\WxSearchRepositores;
use App\Http\Controllers\Api\Repositories\WxShopGoodsRepositories;
use App\Http\Controllers\Api\Repositories\WxUserRepositores;
use App\Jobs\Search\ElasticSearchBatchSyncJob;
use App\Models\Posts\WxPost;
use App\Models\Posts\WxUserCircle;
use App\Models\Circle\WxCircle;
use App\Models\Shop\WxShopGoods;
use App\Models\User\WxUser;
use App\Models\User\WxUserFollow;

class SearchUtils{
    public static function is_use_es(){
        global $__MINI_GLOBAL_PAYCODE_1__;
        if($__MINI_GLOBAL_PAYCODE_1__ && !_empty_(env('ELASTICSEARCH_HOST'))){
            return true;
        }
        return false;
    }

    public static function search_post($actree, $keyword, $uid = 0, $limit = 10, $is_tenant = false){
        global $__MINI_GLOBAL_TENANT_ID__;
        if(self::is_use_es()){
            try {
                // 开启了es
                WxSearchRepositores::record($uid, $keyword);
                $query = WxPost::search($keyword);
                if($is_tenant){
                    $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
                }
                $data = $query->where('is_examine', 1)->where('posts_state', 0)->simplePaginate($limit);
                if($is_tenant){
                    PostUtils::$force_show_multi_site = false;
                }
                $data = PostsRepositores::postsParame($data, $uid,10, $actree);//文章详情
                return $data;
            }catch (\Exception $e){
                if(strpos($e->getMessage(), '404 Not Found') !== false){
                    ElasticSearchBatchSyncJob::dispatch(0, 1000, 'post');
                }else{
                    _logger_(__file__, __line__, $e->getMessage());
                }
            }
        }else{
            return PostsRepositores::searchPosts($keyword, $uid, $limit, $is_tenant);
        }
    }

    public static function search_post_count($keyword, $is_tenant = false){
        global $__MINI_GLOBAL_TENANT_ID__;
        if(self::is_use_es()){
            try {
                $query = WxPost::search($keyword);
                if($is_tenant){
                    $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
                }
                $raw_data = $query->where('is_examine', 1)->where('posts_state', 0)->raw();
                if($raw_data){
                    return $raw_data['hits']['total']['value'];
                }
            }catch (\Exception $e){
                if(strpos($e->getMessage(), '404 Not Found') !== false){
                    ElasticSearchBatchSyncJob::dispatch(0, 1000, 'post');
                }else{
                    _logger_(__file__, __line__, $e->getMessage());
                }
            }
        }else{
            $query = WxPost::where('is_examine', 1)->where('posts_state', 0);
            if($is_tenant){
                $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
            }
            return $query->where(function ($query) use ($keyword) {
                    $query->orWhere('posts_content', 'like', '%' . $keyword . '%')
                        ->orWhere('id', $keyword);
                })
                ->count();

        }
        return 0;
    }

    public static function search_goods($actree, $keyword, $uid = 0, $limit = 10){
        if(self::is_use_es()){
            try {
                $data = WxShopGoods::search($keyword)->where('state', 1)->simplePaginate($limit);
                return $data;
            }catch (\Exception $e){
                if(strpos($e->getMessage(), '404 Not Found') !== false){
                    ElasticSearchBatchSyncJob::dispatch(0, 1000, 'goods');
                }else{
                    _logger_(__file__, __line__, $e->getMessage());
                }
            }
        }else{
            return WxShopGoodsRepositories::searchGoods($keyword, $uid, $limit);
        }
    }

    public static function search_cicle($actree, $keyword, $uid = 0, $limit = 10, $is_tenant = false){
        global $__MINI_GLOBAL_TENANT_ID__;
        if(self::is_use_es()){
            try {
                $query = WxCircle::search($keyword);

                if($is_tenant){
                    // todo:
//                    $query = $query->where(function ($query) {
//                        global $__MINI_GLOBAL_TENANT_ID__;
//                        $query->where('tenant_show', -1)
//                            ->orWhere('tenant_show', $__MINI_GLOBAL_TENANT_ID__);
//                    });
                    $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
                }
                $data = $query->where('circle_state', 1)->simplePaginate($limit);
                $data->map(function ($item) use ($uid) {
                    $item->is_follow = (new WxUserCircle())->isFollowCircle($uid, $item->id);
                    $item->posts_count = WxPost::where('circle_id', $item->id)->count() ?? 0;
                    $item->user_circle_count = WxUserCircle::where('circle_id', $item->id)->count() ?? 0;
                });
                return $data;
            }catch (\Exception $e){
                if(strpos($e->getMessage(), '404 Not Found') !== false){
                    ElasticSearchBatchSyncJob::dispatch(0, 1000, 'circle');
                }else{
                    _logger_(__file__, __line__, $e->getMessage());
                }
            }


        }else{
            return WxCircleRepositores::searchCircle($keyword, $uid, $limit, $is_tenant);
        }
    }

    public static function search_circle_count($keyword, $is_tenant = false){
        global $__MINI_GLOBAL_TENANT_ID__;
        if(self::is_use_es()){
            try {
                $query = WxCircle::search($keyword);
                if($is_tenant){
                    $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
                }
                $raw_data = $query->where('circle_state', 1)->raw();
                if($raw_data){
                    return $raw_data['hits']['total']['value'];
                }
            }catch (\Exception $e){
                if(strpos($e->getMessage(), '404 Not Found') !== false){
                    ElasticSearchBatchSyncJob::dispatch(0, 1000, 'circle');
                }else{
                    _logger_(__file__, __line__, $e->getMessage());
                }
            }

        }else{
            $query = WxCircle::where('circle_state', 1);
            if($is_tenant){
                $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
            }
            return $query->where(function ($query) use ($keyword) {
                    $query->orWhere('circle_name', 'like', '%' . $keyword . '%')
                        ->orWhere('circle_introduce', 'like', '%' . $keyword . '%')
                        ->orWhere('id', $keyword);
                })
                ->count();
        }
        return 0;
    }

    public static function search_user($actree, $keyword, $uid = 0, $is_record = true, $limit = 10, $is_tenant = false){
        global $__MINI_GLOBAL_TENANT_ID__;
        if(self::is_use_es()){
            try {
                if($is_record){
                    WxSearchRepositores::record($uid, $keyword);
                }
                $query = WxUser::search($keyword)->where('user_state', 0);
                if($is_tenant){
                    $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
                }
                $data = $query->simplePaginate($limit);
                // ['id', 'weixin_name', 'user_avatar', 'user_introduce']
                $data->map(function ($v) use ($uid) {
                    $v->is_follow_user = (new WxUserFollow())->isFollowUser($uid, $v->id);
                    UserUtils::field_user_privacy($v);
                });
                return $data;
            }catch (\Exception $e){
                if(strpos($e->getMessage(), '404 Not Found') !== false){
                    ElasticSearchBatchSyncJob::dispatch(0, 1000, 'user');
                }else{
                    _logger_(__file__, __line__, $e->getMessage());
                }
            }
        }else{
            return WxUserRepositores::searchUser($keyword, $uid, $limit, $is_record, $is_tenant);
        }
    }

    public static function search_user_count($keyword, $is_tenant = false){
        global $__MINI_GLOBAL_TENANT_ID__;
        if(self::is_use_es()){
            try {
                $query = WxUser::search($keyword);
                if($is_tenant){
                    $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
                }
                $raw_data = $query->where('user_state', 0)->raw();
                if($raw_data){
                    return $raw_data['hits']['total']['value'];
                }
            }catch (\Exception $e){
                if(strpos($e->getMessage(), '404 Not Found') !== false){
                    ElasticSearchBatchSyncJob::dispatch(0, 1000, 'user');
                }else{
                    _logger_(__file__, __line__, $e->getMessage());
                }
            }
        }else{
            $query = WxUser::where(function ($q) use ($keyword) {
                $q->where('user_name', 'like', '%' . $keyword . '%')->orWhere('id', $keyword);
            });
            if($is_tenant){
                $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
            }
            return $query->count();
        }
        return 0;
    }

    public static function split_keywords($keyword){
        if(_empty_($keyword)){
            return null;
        }
        $str_arr = explode(' ', $keyword);
        $results_arr = [];
        foreach ($str_arr as $_str){
            if(preg_match('$[\x{4E00}-\x{9FFF}]$u', $_str)){
                // 中英混杂
                preg_match_all('$[^\x{4E00}-\x{9FFF}]+$u', $_str, $chars);
                $chars = isset($chars[0]) ? $chars[0] : null;
                if($chars){
                    foreach ($chars as $char_){
                        $tmp_arr = self::split_str_chars(explode($char_, $_str)[0]);
                        if($tmp_arr){
                            $results_arr = array_merge($results_arr, $tmp_arr);
                        }
                        $results_arr[] = $char_;
                    }
                }else{
                    $tmp_arr = self::split_str_chars($_str);
                    if($tmp_arr){
                        $results_arr = array_merge($results_arr, $tmp_arr);
                    }
                }
            }else{
                $results_arr[] = $_str;
            }
        }
        return $results_arr;
    }

    public static function split_str_chars($text){
        if(_empty_($text)){
            return null;
        }

        $cind = 0;
        $arr_cont = array();
        for ($i = 0; $i < strlen($text); $i++) {
            if (strlen(substr($text, $cind, 1)) > 0) {
                if (ord(substr($text, $cind, 1)) < 192) { //如果为英文则取1个字节
                    if (substr($text, $cind, 1) != " ") {
                        array_push($arr_cont, substr($text, $cind, 1));
                    }
                    $cind++;
                } elseif(ord(substr($text, $cind, 1)) < 224) {
                    array_push($arr_cont, substr($text, $cind, 2));
                    $cind+=2;
                } else {
                    array_push($arr_cont, substr($text, $cind, 3));
                    $cind+=3;
                }
            }
        }
        return $arr_cont;
    }

}
